package com.jushu.storbox.util.image;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;

import com.jushu.storbox.constant.ClientConfig;

public class NativeImageLoader {
	private LruCache<String, Bitmap> mMemoryCache;

	private static NativeImageLoader mInstance = new NativeImageLoader();

//	private ExecutorService mImageThreadPool = Executors.newFixedThreadPool(10);
	private ExecutorService mImageThreadPool = new ThreadPoolExecutor(10, 10, 0L,
			TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1000));

	private NativeImageLoader() {
		final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

		final int cacheSize = maxMemory / 4;
		mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
			}
		};
	}

	/**
	 * @return
	 */
	public static NativeImageLoader getInstance() {
		return mInstance;
	}

	/**
	 * @param path
	 * @param mCallBack
	 * @return
	 */
	public Bitmap loadNativeImage(final String path,
			final NativeImageCallBack mCallBack) {
		return this.loadNativeImage(path, null, mCallBack);
	}

	/**
	 * @param path
	 * @param mPoint
	 * @param mCallBack
	 * @return
	 */
	@SuppressLint("HandlerLeak")
	public Bitmap loadNativeImage(final String path, final Point mPoint,
			final NativeImageCallBack mCallBack) {
		Bitmap bitmap = getBitmapFromMemCache(path);
		final Handler mHander = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				mCallBack.onImageLoader((Bitmap) msg.obj, path);
			}

		};

		if (bitmap == null) {
			mImageThreadPool.execute(new Runnable() {

				@Override
				public void run() {
//					Bitmap mBitmap = decodeThumbBitmapForFile(path,
//							mPoint == null ? 0 : mPoint.x, mPoint == null ? 0
//									: mPoint.y);
					Bitmap mBitmap = BitmapUtil.createImageThumbnail(path, ClientConfig.LOCAL_THUMBNAIL_WIDTH, ClientConfig.LOCAL_THUMBNAIL_WIDTH);
					Message msg = mHander.obtainMessage();
					msg.obj = mBitmap;
					mHander.sendMessage(msg);
					addBitmapToMemoryCache(path, mBitmap);
				}
			});
		}
		return bitmap;

	}

	/**
	 * @param key
	 * @param bitmap
	 */
	private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		if (getBitmapFromMemCache(key) == null && bitmap != null) {
			mMemoryCache.put(key, bitmap);
		}
	}

	/**
	 * @param key
	 * @return
	 */
	private Bitmap getBitmapFromMemCache(String key) {
		return mMemoryCache.get(key);
	}

	public interface NativeImageCallBack {
		/**
		 * @param bitmap
		 * @param path
		 */
		public void onImageLoader(Bitmap bitmap, String path);
	}
}
